/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 *
 */

import { cloneDeep } from '@baize/wdk';
import { hvigor, hvigorConfig, HvigorLogger } from '@ohos/hvigor';
import { ClassTypeConst } from '@ohos/hvigor/src/base/common/options/class-type-const.js';

import { BuildProfileSchemaFileConst } from '../../../const/common-const.js';
import { ProjectBuildProfile } from '../../../options/build/project-build-profile.js';
import { AbstractBuildProfileLoader } from './abstract-build-profile-loader.js';

class ProjectBuildProfileLoader extends AbstractBuildProfileLoader {
  private logger: HvigorLogger = HvigorLogger.getLogger(ProjectBuildProfileLoader.name);

  getBuildProfile(): ProjectBuildProfile.ProjectProfileOpt {
    return this.getBuildProfileJson5Obj(hvigor.getRootNode().getNodeName(), true, ClassTypeConst.HVIGOR_PROJECT);
  }

  public setBuildProfileJson5Obj(hvigorNodeName: string, buildProfileJson5Obj: ProjectBuildProfile.ProjectProfileOpt, schemaCheck = true): void {
    super.setBuildProfileJson5ObjCheck(
      hvigorNodeName,
      buildProfileJson5Obj,
      BuildProfileSchemaFileConst.PROJECT_BUILD_PROFILE_SCHEMA_PATH,
      ClassTypeConst.HVIGOR_PROJECT,
    );
  }

  protected initializeReplace(json5Obj: ProjectBuildProfile.ProjectProfileOpt): ProjectBuildProfile.ProjectProfileOpt {
    return this.replaceTargets(json5Obj);
  }

  private replaceTargets(projectProfileJson: ProjectBuildProfile.ProjectProfileOpt) {
    const result = <ProjectBuildProfile.ProjectProfileOpt>cloneDeep(projectProfileJson);
    hvigor.getRootNode().subNodes((node) => {
      if (!result.modules.some((module) => module.name === node.getNodeName())) {
        const srcPath = hvigorConfig.getNodeDescriptorByName(node.getNodeName())?.srcPath;
        result.modules.push({ name: node.getNodeName(), srcPath: srcPath ?? node.getNodePath() });
      }
      const extraTargets = node.getExtraOption('targets');
      if (extraTargets) {
        const json5ObjModules = result.modules;
        json5ObjModules.forEach((moduleBuildOpt) => {
          if (moduleBuildOpt.name === node.getNodeName()) {
            moduleBuildOpt.targets = extraTargets;
          }
        });
      }
    });
    // 动态删除过滤掉已删除的module
    result.modules = result.modules.filter((module) => {
      return hvigor.getAllNodes().some((node) => node.getNodeName() === module.name);
    });
    return result;
  }

  /**
   * 检查是否能够set替换原有的buildProfile
   * 规则：
   * 1.工程级别的buildProfile文件中product里的 runtimeOs 和 name不能修改
   * 2.工程级别的buildProfile文件中products的数量不能变化
   * @param oldObj
   * @param newObj
   * @private
   */
  public checkBuildProfile(oldObj: ProjectBuildProfile.ProjectProfileOpt, newObj: ProjectBuildProfile.ProjectProfileOpt): void {
    // 检查产品数量是否相同
    if (!oldObj.app.products || !newObj.app.products || oldObj.app.products.length !== newObj.app.products.length) {
      this.logger.printErrorExit('CAN_NOT_ADD_OR_DELETE_PRODUCTS', ['build-profile.json5']);
      return;
    }

    // 检查每个产品的 name 和 runtimeOS 是否匹配
    const oldProducts = oldObj.app.products;
    const newProducts = newObj.app.products;

    oldProducts.forEach((oldProduct) => {
      const matchingProduct = newProducts.find((newProduct) => newProduct.name === oldProduct.name);
      if (!matchingProduct) {
        this.logger.printErrorExit('CAN_NOT_CHANGE_NAME_OR_RUNTIME_PRODUCTS', [oldProduct.name]);
        return;
      }
      if (matchingProduct.runtimeOS !== oldProduct.runtimeOS) {
        this.logger.printErrorExit('CAN_NOT_CHANGE_NAME_OR_RUNTIME_PRODUCTS', [oldProduct.runtimeOS]);
      }
    });
  }
}

export const projectBuildProfileLoader = new ProjectBuildProfileLoader();
